package com.jwaoo.chat.session.avchat;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import com.dx.as.common.CommonUtils;
import com.dx.as.common.log.LogUtil;
import com.dx.as.common.string.StringUtil;
import com.dx.as.common.sys.TimeUtil;
import com.jwaoo.chat.ChatConstants;
import com.jwaoo.chat.ChatHelpter;
import com.jwaoo.chat.Message;
import com.jwaoo.chat.activity.module.fromapp.AppInstance;
import com.jwaoo.chat.data.db.MessageHandler;
import com.jwaoo.chat.session.Extras;
import org.appspot.apprtc.WebRtcClient;
import org.appspot.apprtc.WebRtcInfo;
import org.appspot.apprtc.WebRtcType;
import java.util.Timer;
import java.util.TimerTask;
import static android.content.Context.WINDOW_SERVICE;
import static com.dx.as.config.Config.AVCHAT_WATTING_MAX_TIME;
import static com.jwaoo.chat.data.db.MessageHandler.UPDATE_MESSAGE;
import static com.jwaoo.chat.session.Extras.EXTRA_MESSAGE;
import static com.jwaoo.chat.session.avchat.MessageParse.InteractInfo.STATE_OFFLINE;

/**
 * Created by jwaoo on 2017/10/30.
 */

public class FloatView {
    private AVChatReiceiver messageReiceiver;
    private int avChatType;
    private Message baseMessage;
    private int friendId;
    private WebRtcClient webRtcClient;
    private final String roomUrl = AppInstance.getInstance().getRTCUrl();
    private boolean isComming = false;
    private String roomId;
    private boolean isChating = false;
    private static FloatView floatView;
    private AChatView aChatView;
    private Timer timer;
    private TimerTask task;
    private TimerTask taskRecord;
    private boolean isFront = false;
    private Timer timer2;
    private String TAG = FloatView.class.getSimpleName();
    private int num = 0;
    private BluetoothView bluetoothView;
    private WindowManager windowManager;
    private int otherDivType;
    private int localDivType;
    public static FloatView getInstance(){
        if (floatView == null){
            synchronized (FloatView.class){
                if (floatView == null){
                    floatView = new FloatView();
                }
            }
        }
        return floatView;
    }

    public boolean isStart(){
        return isChating;
    }

    public void launch(Message message){
        sendP2PBroad(Extras.EXTRA_MESSAGE_HIDE_KEY_BOARD);
        if (isBackGround) {
            isBackGround = false;
            aChatView.hideFloatView(false);
            return;
        }
        isChating = true;
        initRecieiver();
        initHomeDownRecieiver();
        parseIntent(message);
        windowManager = (WindowManager) ChatHelpter.getContext().getSystemService(WINDOW_SERVICE);
        aChatView = new AChatView(windowManager,listener,avChatType,isComming);
        if (!CommonUtils.isEnFloat()){
            AVChatActivity.startAVChatActivity();
        }else {
            initWebRtc();
        }

    }

    private FloatView(){

    }

    public View getBaseView(){
        return aChatView.getBaseView();
    }

    public View getBluetoothBaseView(){
        return bluetoothView.getBaseView();
    }


    public void initWebRtc(){
        webRtcClient = new WebRtcClient(ChatHelpter.getContext(),roomUrl,roomId, aChatView.getSmallView(), aChatView.getFullscreenRenderer());
        webRtcClient.setRtcCallStateChange(rtcCallStateChange);
        webRtcClient.setSpeakerEnable(true);
        webRtcClient.setVoiceChannelEnable(true);
        if (!isComming) {
            webRtcClient.call();
            AVChatSoundPlayer.instance().play(AVChatSoundPlayer.RingerTypeEnum.RING);
        }

        if (avChatType == AVChatType.VIDEO.getValue()) webRtcClient.setVideoChannelEnable(true);
        else {
            webRtcClient.setVideoChannelEnable(false);
        }
        timer = new Timer();
        task = new TimerTask() {
            @Override
            public void run() {
                baseMessage.getAttachment().setDuration(baseMessage.getAttachment().getDuration() + 1);
                MessageHandler.getInstace(ChatHelpter.getContext()).handlerMessages(MessageHandler.UPDATE_MESSAGE,baseMessage);
                aChatView.updateTime(TimeUtil.secToTime((int)baseMessage.getAttachment().getDuration()));
            }
        };

        onTimeStart();
    }


    private void onBtnClick(AVChatState type){
        baseMessage.getAttachment().setAttachstate(type.getValue());
        sendMessage("",type.getValue());
        MessageHandler.getInstace(ChatHelpter.getContext()).handlerMessages(UPDATE_MESSAGE,baseMessage);
        doHangUp();
    }

    public void onHangUpBtnClick(){
        onBtnClick(AVChatState.hangup);
    }

    private void finshChat() {
        try {
            task.cancel();
            timer.cancel();
            onStopTime();
        } catch (Exception ex) {
            LogUtil.e(TAG, ex.toString());
        }
        isChating = false;
        ChatHelpter.getContext().unregisterReceiver(messageReiceiver);
        distoryHomeDownReiceiver();

        if (CommonUtils.isEnFloat()){
            aChatView.removeView();
            if (bluetoothView != null) {
                bluetoothView.doBluetoothOption(currentMode, 0, true);
                bluetoothView.closeBluetoothView();
                bluetoothView.onDestoryBluetooth();
            }
        }else {
            AVChatActivity.doHangUp();
        }

        aChatView = null;
        isAccept = false;
        bluetoothView = null;
        otherDivType = 0;
        localDivType = 0;
        num = 0;
        sendP2PBroad(null);
    }

    private void sendP2PBroad(String key){
        Intent intentMessage = new Intent();
        intentMessage.setAction(ChatConstants.ACTION_MESSAGE);
        if (key == null){
            intentMessage.putExtra(Extras.EXTRA_MESSAGE,baseMessage);
        }else {
            intentMessage.putExtra(key,true);
        }
        ChatHelpter.getContext().sendBroadcast(intentMessage);
    }


    private void parseIntent(Message message){
        roomId = message.getAttachment().getRoomid();
        isComming = true;
        if (StringUtil.isEmpty(roomId)){
            roomId = WebRtcClient.ROOM_REQUEST_ID;
            isComming = false;
        }else {
            AVChatSoundPlayer.instance().play(AVChatSoundPlayer.RingerTypeEnum.RING);
        }
        avChatType = message.getMsgtype();
        friendId = message.getFriend();
        baseMessage = message;
    }

    private WebRtcClient.RtcCallStateChange rtcCallStateChange = new WebRtcClient.RtcCallStateChange() {
        @Override
        public void onHangUp() {
            baseMessage.getAttachment().setAttachstate(AVChatState.hangup.getValue());
            MessageHandler.getInstace(ChatHelpter.getContext()).handlerMessages(UPDATE_MESSAGE,baseMessage);
            doHangUp();
        }

        @Override
        public void onReportError(String s) {
        }

        @Override
        public void onConnectedToRoom(boolean b, String s) {
            Log.e("===","onConnectedToRoom");
            if (!isComming){
                if (b){
                    sendMessage(s,AVChatState.request.getValue());
                }
                LogUtil.w("AVChat","connected : "+b);
            }else {
                LogUtil.w("AVChat","isComming connected : "+b);
            }
        }

        @Override
        public void onReportStats(WebRtcInfo webRtcInfo) {
            if (aChatView != null)
                aChatView.onLog(webRtcInfo.toString());
        }

        @Override
        public void onP2PConnectionStateChanged(WebRtcType.P2PConnectionState p2PConnectionState) {
            if (p2PConnectionState == WebRtcType.P2PConnectionState.P2PCS_IceConnected){
                AVChatSoundPlayer.instance().stop();
                timer.schedule(task,1000,1000);
                isChating = true;
                onStopTime();
                Handler handler = aChatView.getHandler();
                if (handler != null) {
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            aChatView.onConnected();
                        }
                    },1500);
                }else {
                    aChatView.onConnected();
                }


            } else if (p2PConnectionState == WebRtcType.P2PConnectionState.P2PCS_IceDisconnected){
                baseMessage.getAttachment().setAttachstate(AVChatState.hangup.getValue());
                MessageHandler.getInstace(ChatHelpter.getContext()).handlerMessages(UPDATE_MESSAGE,baseMessage);
                doHangUp();
            } else if (p2PConnectionState == WebRtcType.P2PConnectionState.P2PCS_RemoteVoiceChannelOpen) {
                aChatView.hideSmallView(true,false);
                webRtcClient.swapRender(isFront = !isFront);
                aChatView.onRemoteCameraClosed(false);
            } else if (p2PConnectionState == WebRtcType.P2PConnectionState.P2PCS_RemoteVoiceChannelClose){
                if (aChatView == null) return;
                webRtcClient.swapRender(isFront = !isFront);
                aChatView.onRemoteCameraClosed(true);
                aChatView.hideSmallView(true,true);
            }
            LogUtil.d("AVChat","state : "+p2PConnectionState.name());
            Log.e("===","onConnectedToRoom");
        }
        @Override
        public void onDataSimpleMessage(String s) {
            Log.e("===","onDataSimpleMessage : "+s);
        }

        @Override
        public void onDataControllerMessage(String s) {
            Log.e("===","onDataControllerMessage : "+s);
            parseInfo(s);
        }

        @Override
        public void onAudioRouteChanged(boolean b) {
            //标记Audio状态 ，true 扬声器
            //webRtcClient.setSpeakerEnable(); 设置扬声器
        }
    };

    private void doHangUp(){
        try{
                    //通知聊天也刷新数据
            if (webRtcClient != null){
                webRtcClient.hangUp();
                webRtcClient.setRtcCallStateChange(null);
            }
            AVChatSoundPlayer.instance().stop();
            finshChat();
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }

    private void initRecieiver(){
        messageReiceiver = new AVChatReiceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ChatConstants.ACTION_AV_MESSAGE);
        ChatHelpter.getContext().registerReceiver(messageReiceiver, intentFilter);
    }

    public class AVChatReiceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Message message = (Message)intent.getSerializableExtra(EXTRA_MESSAGE);
            if (message.getFriend() == friendId){
                if (message.getAttachment().getAttachstate() == AVChatState.refused.getValue()){
                    doHangUp();
                }else if (message.getAttachment().getAttachstate() == AVChatState.busy.getValue()){
//                    Toast.makeText(getApplicationContext(),"对方正忙...",Toast.LENGTH_LONG).show();
                }else if (message.getAttachment().getAttachstate() == AVChatState.cancel.getValue() || message.getAttachment().getAttachstate() == AVChatState.missed.getValue()){
                    doHangUp();
                }else if (message.getAttachment().getAttachstate() == AVChatState.hangup.getValue()){
//                    doHangUp();
                }
                baseMessage = message;
            }else {
                sendMessage("",AVChatState.busy.getValue());
            }
        }
    }

    private void sendMessage(String chanel ,int state){
        baseMessage.getAttachment().setRoomid(chanel);
        baseMessage.getAttachment().setAttachstate(state);
        MessageHandler.getInstace(ChatHelpter.getContext()).sendMessage(baseMessage);
    }


    private void onStopTime(){
        taskRecord.cancel();
        timer2.cancel();
    }

    private void onTimeStart(){
        timer2 = new Timer();
        taskRecord = new TimerTask() {
            @Override
            public void run() {
                num++;
                if (num == AVCHAT_WATTING_MAX_TIME) {
                    baseMessage.getAttachment().setAttachstate(AVChatState.missed.getValue());
                    MessageHandler.getInstace(ChatHelpter.getContext()).handlerMessages(UPDATE_MESSAGE,baseMessage);
                    sendMessage("",AVChatState.missed.getValue());
                    aChatView.showTagInfo();
                    aChatView.getHandler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            doHangUp();
                        }
                    },1500);
                }
            }
        };
        timer2.schedule(taskRecord,1000,1000);
    }


    private AChatView.CallbackListener listener = new AChatView.CallbackListener() {
        @Override
        public void onButtonClick(AVChatState avChatState) {
            onBtnClick(avChatState);
        }

        @Override
        public void onSwapRender() {
            webRtcClient.swapRender(isFront = !isFront);
        }

        @Override
        public void onSwitchCamera() {
            webRtcClient.switchCamera();
        }

        @Override
        public void onStartAvChat() {
            webRtcClient.call();
        }

        @Override
        public void onCloseCamera(boolean close) {
            webRtcClient.setVideoChannelEnable(!close);
        }

        @Override
        public void onHang() {
            doHangUp();
        }

        @Override
        public void onConnectBluetooth() {
            if (bluetoothView == null) {
                bluetoothView = new BluetoothView(windowManager,selectedListener);
            }
            bluetoothView.showView();
        }

        @Override
        public void onRequestDiv() {
            if (otherDivType != MessageParse.InteractInfo.DIV_TYPE_SENSE_VIBE && localDivType != MessageParse.InteractInfo.DIV_TYPE_SENSE_VIBE) {
                AVChatDialog.getInstance().showDialog(windowManager,0,null,null);
                return;
            }
            sendRequestDiv(0);
        }

        @Override
        public void onMeiYan() {
            webRtcClient.setBeautifyEnable(isMeiyan = !isMeiyan);
        }

        @Override
        public void onBluetoothOption(int mode, int level) {
            sendOptonDiv(mode,level);
        }
    };

    private BluetoothView.OnItemSelectedListener selectedListener = new BluetoothView.OnItemSelectedListener() {
        @Override
        public void onConnected(boolean isConnected,String name) {
            localDivType = MessageParse.getDivtype(name);
            aChatView.onDivConnected(isConnected);
            sendDivState(isConnected,name);
        }

        @Override
        public void onOptionSpeed(int speed) {
            if (otherDivType != MessageParse.InteractInfo.DIV_TYPE_SENSE_VIBE && localDivType != MessageParse.InteractInfo.DIV_TYPE_SENSE_VIBE) {
                AVChatDialog.getInstance().showDialog(windowManager,0,null,null);
                return;
            }
            if (isAccept)
                sendOptonDiv(currentMode,speed,true);
        }
    };

    private boolean isMeiyan = true;
    private int currentMode = 1;

    private void sendOptonDiv(int mode,int level) {
        sendOptonDiv(mode,level,false);
    }

    private void sendOptonDiv(int mode,int level,boolean isSpeedByFreq){
        currentMode = mode;
        MessageParse.InteractInfo interactInfo = new MessageParse.InteractInfo();
        interactInfo.setDivtype(localDivType);
        interactInfo.setOnline(MessageParse.InteractInfo.STATE_ONLINE);
        interactInfo.setMsgtype(MessageParse.InteractInfo.MSG_TYPE_ACTION);
        interactInfo.setDivmode(mode);
        interactInfo.setSpeedByFreq(isSpeedByFreq);
        interactInfo.setLevel(level);
        String json = MessageParse.createInteractMessage(interactInfo);
        webRtcClient.sendControllerMsg(json);
        LogUtil.d("===",""+json);
    }

    private void sendRequestDiv(int type){
        MessageParse.InteractInfo interactInfo = new MessageParse.InteractInfo();
        interactInfo.setDivtype(localDivType);
        interactInfo.setOnline(MessageParse.InteractInfo.STATE_ONLINE);
        interactInfo.setMsgtype(MessageParse.InteractInfo.MSG_TYPE_REQUEST);
        interactInfo.setRequest_state(type);
        String json = MessageParse.createInteractMessage(interactInfo);
        webRtcClient.sendControllerMsg(json);
    }

    private void sendDivState(boolean isConnected ,String name){
        MessageParse.InteractInfo interactInfo = new MessageParse.InteractInfo();
        interactInfo.setDivtype(MessageParse.getDivtype(name));
        interactInfo.setOnline(isConnected ? MessageParse.InteractInfo.STATE_ONLINE : STATE_OFFLINE);
        interactInfo.setMsgtype(MessageParse.InteractInfo.MSG_TYPE_ONLINE_STATE);
        String json = MessageParse.createInteractMessage(interactInfo);
        webRtcClient.sendControllerMsg(json);
    }


    private void parseInfo(String msg){
        final MessageParse.InteractInfo interpolator = MessageParse.parseDate(msg);
        if (interpolator != null){

            switch (interpolator.getMsgtype()){
                case 1:
                    otherDivType = interpolator.getDivtype();
                    aChatView.onOtherDivConnected(otherDivType != 0);
                    break;
                case 2:
                    aChatView.getHandler().post(new Runnable() {
                        @Override
                        public void run() {
                            if (interpolator.getRequest_state() == 0 && !isAccept){
                                AVChatDialog.getInstance().showDialog(windowManager, 1, new View.OnClickListener() {
                                    @Override
                                    public void onClick(View v) {
                                        sendRequestDiv(MessageParse.InteractInfo.REQUSET_TYPE_REJECT);
                                    }
                                }, new View.OnClickListener() {
                                    @Override
                                    public void onClick(View v) {
                                        if (interpolator.getDivtype() == MessageParse.InteractInfo.DIV_TYPE_SENSE_VIBE) {
//                                            aChatView.hideBottomView(true);
                                            aChatView.doAccept();
                                        } else {
                                            sendRequestDiv(MessageParse.InteractInfo.REQUSET_TYPE_ACCEPT);
                                        }
                                        isAccept = true;
                                    }
                                });
                            }else if (interpolator.getRequest_state() == MessageParse.InteractInfo.REQUSET_TYPE_REJECT){
                                AVChatDialog.getInstance().showDialog(windowManager,2,null,null);
                            }else if (interpolator.getRequest_state() == MessageParse.InteractInfo.REQUSET_TYPE_ACCEPT ){
                                if ( otherDivType == MessageParse.InteractInfo.DIV_TYPE_SENSE_VIBE ){
//                                    aChatView.hideBottomView(true);
                                    aChatView.doAccept();
                                }
                                isAccept = true;
                            }
                        }
                    });

                    break;
                case 3:
                    if (bluetoothView != null)
                    //操作神器
                        bluetoothView.doBluetoothOption(interpolator.getDivmode(),interpolator.getLevel(),interpolator.isSpeedByFreq());
                    break;
            }
        }
    }

    private boolean isAccept = false;
    private OnHomeDownReiceiver homeDownReiceiver;
    private void initHomeDownRecieiver(){
        homeDownReiceiver = new OnHomeDownReiceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(CommonUtils.getActionHomeDown());
        ChatHelpter.getContext().registerReceiver(homeDownReiceiver, intentFilter);
    }

    private void distoryHomeDownReiceiver(){
        ChatHelpter.getContext().unregisterReceiver(homeDownReiceiver);
    }

    private boolean isBackGround = false;

    private class OnHomeDownReiceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (CommonUtils.isEnFloat()){
                if (isChating){
                    aChatView.onScaleBtnClicked();
                }else {
                    aChatView.hideFloatView(true);
                    isBackGround = true;
                }
            }
        }
    }
}
